﻿namespace MiniCore;

/// <summary>
/// HttpHandler就等于Application 中间件集合业务集合
/// </summary>
public interface IApplicationBuilder
{
    /// <summary>
    /// 中间件注册 use
    /// 中间件在ASP.NET Core被表示成一个Func<RequestDelegate, RequestDelegate>对象
    /// 对于管道的中的某一个中间件来说，由后续中间件组成的管道体现为一个RequestDelegate对象，由于当前中间件在完成了自身的请求处理任务之后，往往需要将请求分发给后续中间件进行处理，
    /// 所有它它需要将由后续中间件构成的RequestDelegate作为输入。
    /// 当代表中间件的委托对象执行之后，我们希望的是将当前中间件“纳入”这个管道，那么新的管道体现的RequestDelegate自然成为了输出结果
    /// </summary>    
    IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);
    RequestDelegate Build();
}


public class ApplicationBuilder : IApplicationBuilder
{
    /// <summary>
    /// HttpHandler,中间件集合
    /// </summary>
    private readonly List<Func<RequestDelegate, RequestDelegate>> _middlewares = new List<Func<RequestDelegate, RequestDelegate>>();

    /// <summary>
    /// 中间件管道构建
    /// </summary>    
    public RequestDelegate Build()
    {
        _middlewares.Reverse();
        return HttpContext =>
        {
            // 默认404
            RequestDelegate next = _ => { _.Response.StatusCode = 404; return Task.CompletedTask; };
            foreach (var middleware in _middlewares)
            {
                next = middleware(next);
            }
            return next(HttpContext);
        };
    }

    /// <summary>
    /// 中间件添加
    /// </summary>
    /// <param name="middleware"></param>    
    public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
    {
        _middlewares.Add(middleware);
        return this;
    }
}
